module ShiftMultiplier #(
    parameter WIDTH = 64,
    parameter E = WIDTH + 2,
    parameter W = E * 2,
    parameter N = E / 2
) (
    input   logic               clock,
    input   logic               reset,
    input   logic [WIDTH-1:0]   x,
    input   logic [WIDTH-1:0]   y,
    input   logic [1:0]         signs,
    input   logic               valid,
    output  logic               ready,
    output  logic [2*WIDTH-1:0] result,
    output  logic               done
);
    wire sign;
    assign ready = (state == IDLE);
    assign done  = (state == DONE);
    assign result = R[2*WIDTH-1:0];

    // Booth's Algorithm
    logic [E:0]     Y;
    logic [W-1:0]   X;
    logic [W-1:0]   R;
    logic [W-1:0]   P;
    logic           C;
    Radix4BoothProduct #(
        .WIDTH(W)
    ) booth (
        .y      (Y[2:0]),
        .x      (X[W-1:0]),
        .p      (P),
        .c      (C)
    );

    // Adder
    wire [W-1:0]    adder_x     = R;
    wire [W-1:0]    adder_y     = P;
    wire            adder_cin   = C;

    logic [W-1:0]   adder_sum;
    /* verilator lint_off UNUSEDSIGNAL */
    logic           adder_cout;

    /* verilator lint_off WIDTH */
    assign {adder_cout, adder_sum} = adder_x + adder_y + adder_cin;

    // State Machine
    localparam IDLE = 3'b001, CALC = 3'b010, DONE = 3'b100;
    logic [2:0] state;
    logic       y_sign;

    always_ff @(posedge clock) begin
        if (reset) begin
            state   <= IDLE;
            y_sign  <= 0;
            X   <= 0;
            Y   <= 0;
            R   <= 0;
        end
        else begin
            case (state) 
                IDLE: begin
                    if (valid & ready) begin
                        state   <= CALC;
                        y_sign  <= signs[0] & y[WIDTH-1];
                        X   <= { {(WIDTH+4){signs[1] ? x[WIDTH-1] : 1'b0}}, x};
                        Y   <= { { 2{signs[0] ? y[WIDTH-1] : 1'b0}}, y, 1'b0 };
                        R   <= 0;
                    end
                    else begin
                        state   <= IDLE;
                    end
                end
                CALC: begin
                    // 不全为 0
                    if (y_sign ? (|Y[E-1:1]) : (|Y)) begin
                        state   <= CALC;
                        X   <= {X[W-1:0], 2'b00}; // X   <= X << 2;
                        Y   <= {2'b00, Y[E:2]};   // Y   <= Y >> 2;
                        R   <= adder_sum;
                    end
                    // 全为 0
                    else begin
                        state   <= DONE;
                    end
                end
                DONE: begin
                    state   <= IDLE;
                end
                default: begin
                    state   <= IDLE;
                end
            endcase
        end
    end
    
endmodule //Multiplier
